package com.yupi.project.handler;

import com.yupi.project.manager.RedisLimiterManager;
import com.yupi.project.model.AuthenticatorResult;
import com.yupi.project.model.ProtectedRequest;
import com.yupi.project.model.RequestHolder;
import com.yupi.project.model.RequestInfo;
import com.yupi.project.security.SecurityVerificationHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @description: Redission接口限流
 * @author SummerBird
 * @date 2024/3/8 19:17
 * @version 1.0
 */
@Component
@Slf4j
public class RedisLimiterHandler implements SecurityVerificationHandler {

    private static final String KEY_PREFIX = "interface:invoke:";

    @Resource
    private RedisLimiterManager redisLimiterManager;

    @Override
    public AuthenticatorResult auth(ProtectedRequest protectedRequest) {
        RequestInfo requestInfo = RequestHolder.get();
        RequestInfo.UserInfo invokeUser = requestInfo.getUserInfo();
        RequestInfo.InterfaceInvokeInfo interfaceInfo = requestInfo.getInterfaceInvokeInfo();
        // 接口限流，限制用户在接口上的调用频率。默认是单个用户1秒至多调用5次
        String key = KEY_PREFIX + invokeUser.getId() + ":" + interfaceInfo.getId();
        Integer rate = interfaceInfo.getRate();
        Integer rateInterval = interfaceInfo.getRateInterval();
        Integer rateIntervalUnit = interfaceInfo.getRateIntervalUnit();
        try {
            redisLimiterManager.doRateLimit(key, rate, rateInterval, rateIntervalUnit);
        } catch (Exception e){
            log.error("调用过于频繁，稍后重试");
            return AuthenticatorResult.fail("调用过于频繁，稍后重试");
        }
        return AuthenticatorResult.success();
    }

    @Override
    public int getOrder() {
        return 9;
    }
}
